#include <iostream>

using namespace std;

/*每次落子共含四步
    接受落子，判定是否合法。
    根据落子，修改棋盘状态。
    根据落子，判定是否五子连线。
    输出棋盘状态。*/

class chessBoard {
public:
    chessBoard()//棋盘初始化
    {
        for(int i=0; i<=18; i++)
        {
            for(int j=0; j<=18; j++)
            {
                board[i][j]='0';
            }
        }
    }
    
    //判断本次的落子是否合法，不能超过边界，落子的地方也不能已经有子
    int isLegal(int take, int x, int y)
    {
        //使用数组的第三行到第17行，第三列到第17列，暂时没有想出如果搜索时数组角标越界的方法
        if(x>16 || x<2 || y>16 || y<2)
            return 0;
        else if(board[x][y]!='0')
            return 0;
        else
            return 1;
    }
    
    //下子
    void upgrade(int take, int x, int y)
    {
        switch(take)
        {
            case 1: board[x][y]='#'; break;
            case 2: board[x][y]='$'; break;
        }
    }
    
    //判断落子四条线上是否满足五子要求
    int iswin(int take, int x, int y);
    
    //只打印15*15的棋盘，下棋要注意
    void print()
    {
        for(int i=2; i<=16; i++)
        {
            for(int j=2; j<=16; j++)
            {
                cout<<board[i][j]<<' ';
            }
            cout<<endl;
        }
    }
    
private:
    char board[19][19]; //棋盘制成15*15，为防止搜索时数组越界改为19*19的数组
};

int chessBoard::iswin(int take, int x, int y){
    int sum;
    for(int i=0;i<19;i++){
        for(int j=0;j<19;j++)
        {
            //纵五子
            sum=0;
            for(int k=1;k<6;k++)
            {
                if('0'== board[x][y+k])
                    break;
                else if(board[x][y+k]==board[x][y+k-1])
                    sum+=1;
                if(sum==5)
                    return 1;
            }
            
            //横五子
            sum=0;
            for(int k=1;k<6;k++)
            {
                if('0'==board[x+k][y])    break;
                else if(board[x+k][y]==board[x+k-1][y])
                    sum+=1;
                if(sum==5)
                    return 1;
            }
            
            //左斜五子
            sum=0;
            for(int k=1;k<6;k++)
            {
                if('0' == board[x+k][y+k]) break;
                else if(board[x+k][y+k]==board[x+k-1][y+k-1])
                    sum+=1;
                if(sum==5)
                    return 1;
            }
            
            //右斜五子
            sum=0;
            for(int k=1;k<6;k++)
            {
                if('0'==board[x-k][y-k])    break;
                else if(board[x+k][y-k]==board[x+k-1][y-k+1])
                    sum+=1;
                if(sum==5)
                    return 1;
            }
        }
    }
    return 0;
}

int main() {
    int x,y;
    int take;
    int n;
    int flag;
    
    flag=0;
    cout<<"这局游戏最多多少颗棋子"<< endl;
    cin>>n;
    chessBoard game;
    
    while(n--)
    {
        cout<<"请输入您是第几个开始下棋的以及落子的坐标(数字 数字 数字,如2 4 4 ):"<<endl;
        cin>>take>>x>>y;
        if(game.isLegal(take, x, y))
        {
            game.upgrade(take, x, y);
            game.print();
            if(game.iswin(take, x, y))
            {
                flag=1;
                break;
            }
        }
    }
    
    if(flag==1)
    {
        if(take==1)
            cout<<"黑子胜"<<endl;
        else if(take==2)
            cout<<"白子胜"<<endl;
    }
    else
    {
        if(take==1)
            cout<<"白子继续"<<endl;
        else if(take==2)
            cout<<"黑子继续"<<endl;
    }
    
    cout<<endl;
    
    return 0;
}

/*自己编写的五子棋小程序，尽量使用了学过的类的知识
还有很多功能没有实现比较粗糙。数组搜索越界的问题没什么好的解决思路，只能是将数组简单的扩大了两圈。*/

// FIXME:
//  1. 做的很好！继续努力
//  2. 将数组扩大两圈是一个很好的处理方法，简单高效。当然也可以想想其他的方法
//  3. 可以考虑自动算最优位置的方法，这样你就可以和电脑对弈了
//  4. 代码格式参考我给你修改的，适当的地方加上空行，这样程序的层次关系看着更清楚
